package iut.picturama;

import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.MediaStore;
import android.text.InputType;
import android.util.DisplayMetrics;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MenuItem.OnMenuItemClickListener;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.FrameLayout.LayoutParams;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity implements OnClickListener, OnMenuItemClickListener {

	private RelativeLayout relLay;
	private LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
	private SharedPreferences prefs;

	private boolean isWin = false;
	
	private Button butSplitDeuxXTrois;
	private Button butSplitQuatreXSix;
	private Button butSplitHuitXHuit;
	private Button butAutreImage;

	private static final int MAX_NB_PICTURE = 8;
	private static final int DECALAGE = 4;
	private ImageView imgIsee[]  = new ImageView[1+MAX_NB_PICTURE*MAX_NB_PICTURE];

	private Bitmap bip[] = new Bitmap[2+MAX_NB_PICTURE*MAX_NB_PICTURE];
	private Bitmap bmpEmpty;

	private int calculatedWidth = 0;
	private int calculatedHeight = 0;
	private int posEmpty = 0;
	private Random r = new Random();
	private List<Integer> randomList = new ArrayList<Integer>();
	private int nbL = 0;
	private int nbC = 0;
	private int nbImageViewCreated = 0;

	private TextView textCoup;
	private int nbCoup = 0;

	private static final int SELECT_PHOTO = 100;
	private static final int CAMERA_REQUEST = 1888;

	private Context context;

	private AlertDialog.Builder builder1;
	private AlertDialog.Builder builder2;
	private EditText inputURL;
	private String url = "";

	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		DisplayMetrics displaymetrics = new DisplayMetrics();
		getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
		int SCREENh = displaymetrics.heightPixels;
		int SCREENw = displaymetrics.widthPixels;

		context = getApplicationContext();
		prefs = this.getSharedPreferences("iut.picturama", Context.MODE_PRIVATE);

		//RelativeLayout
		relLay = (RelativeLayout) findViewById(R.id.relLay);
		relLay.setBackgroundColor(Color.argb(200, 255, 255, 204));

		//ImageView original
		imgIsee[0] = (ImageView)findViewById(R.id.imgisee);
		imgIsee[0].getLayoutParams().height = SCREENh/2-DECALAGE*25;
		imgIsee[0].getLayoutParams().width = SCREENw-DECALAGE*6;

		//TextView des scores
		textCoup = (TextView)findViewById(R.id.nbCoup);

		//Button +actions integrees sinon probleme
		butSplitDeuxXTrois = (Button)findViewById(R.id.butSplitDeuxXTrois);
		butSplitDeuxXTrois.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				textCoup.setText("Coups : "+nbCoup);
				createBitmap(nbL = 2, nbC = 3);
				buttonsSetVisibility(View.INVISIBLE);
			}
		});

		butSplitQuatreXSix = (Button)findViewById(R.id.butSplitQuatreXSix);
		butSplitQuatreXSix.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				textCoup.setText("Coups : "+nbCoup);
				createBitmap(nbL = 4, nbC = 6);
				buttonsSetVisibility(View.INVISIBLE);
			}
		});

		butSplitHuitXHuit = (Button)findViewById(R.id.butSplitHuitXHuit);
		butSplitHuitXHuit.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				textCoup.setText("Coups : "+nbCoup);
				createBitmap(nbL = 8, nbC = 8);
				buttonsSetVisibility(View.INVISIBLE);
			}
		});

		/* AlertDialog pour le button Autre Image */
		builder1 = new AlertDialog.Builder(this);
		builder2 = new AlertDialog.Builder(this);
		inputURL = new EditText(this);
		inputURL.setInputType(InputType.TYPE_CLASS_TEXT);

		butAutreImage = (Button)findViewById(R.id.butSplitAutre);
		butAutreImage.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				//Creation des choix
				String[] selector = {"Appareil photo", "Internet", "Galerie"};
				//Creation de la premiere AlertDialog pour le choix des sources
				builder1.setTitle("Source")
				.setItems(selector, new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int index)
					{
						//index = numero de source
						switch(index)
						{
						//Appareil photo
						case 0:
							Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); 
							startActivityForResult(cameraIntent, CAMERA_REQUEST);
							break;

						//Internet
						case 1:
							if(isOnline()==true)
							{
								String sURL = null;//"http://www.clipart-fr.com/data/wallpaper/Animaux/animaux_067.jpg"
								//Creation de la deuxieme AlertDialog pour entrer le lien vers l'image
								builder2.setTitle("Lien")
								.setView(inputURL)
								.setPositiveButton("OK", new DialogInterface.OnClickListener() { 
									public void onClick(DialogInterface dialog, int which) {
										url = inputURL.getText().toString();
									}
								})
								.setNegativeButton("Annuler", new DialogInterface.OnClickListener() {
									public void onClick(DialogInterface dialog, int which) {
										dialog.cancel();
									}
								})
								.show();

								sURL = url;
								imgIsee[0].setTag(sURL);
								new DownloadImagesTask().execute(imgIsee[0]);
							}
							else
							{
								Toast.makeText(context, "Vous n'etes pas connecte a internet !", Toast.LENGTH_LONG).show();
							}
							break;
						//Galerie
						case 2:
							Intent photoPickerIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
							startActivityForResult(photoPickerIntent, SELECT_PHOTO);
							break;
						}
					}
				})
				.setNegativeButton("Annuler", new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int which)
					{
						dialog.cancel(); // fermeture de l'AlertDialog.Builder
					}
				})
				.show();
			}
		});
	}

	/* Gestion des touches appuye */
	public boolean onKeyDown(int keyCode, KeyEvent event) 
    {
		/* Si touche retour appuye, on relance l'activity */
        if (keyCode == KeyEvent.KEYCODE_BACK)
        {
        	super.recreate();
        	return true;
        }
        return super.onKeyDown(keyCode, event);
     }
	
	/* Gere la creation du menu */
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		menu.findItem(R.id.action_settings_holeColor).setOnMenuItemClickListener(this);
		return true;
	}

	/* Gere le clique Item dans le menu */
	public boolean onMenuItemClick(MenuItem item) {
		switch(item.getItemId())
		{
		case R.id.action_settings_holeColor:
			AlertDialog.Builder builder = new AlertDialog.Builder(this);
			String[] holeColors = {"Noir", "Transparent"};
			builder.setTitle("Couleur de l'emplacement vide")
			.setItems(holeColors, new DialogInterface.OnClickListener() {
				public void onClick(DialogInterface dialog, int index)
				{
					switch(index)
					{
					//Noir
					case 0:
						prefs.edit().putString("iut.picturama.holeColor", Config.RGB_565.toString()).commit();
						break;
					//Transparent
					case 1:
						prefs.edit().putString("iut.picturama.holeColor", Config.ARGB_8888.toString()).commit();
						break;
					}
				}
			})
			.show();
			break;
		}
		return false;
	}
	
	/* Gere les clics sur la vue */
	public void onClick(View v)
	{		
		for(int i=1; i<=MAX_NB_PICTURE*MAX_NB_PICTURE; i++)
		{
			if( v.getTag().equals("ImageView"+i))
			{	
				//Log.e("Image clique",""+i);
				if(verifyNearHole(i)  && isWin == false)
				{
					changePos(i);

					nbCoup++;
					textCoup.setText("Coups : "+nbCoup);

					if(verifWin())
						textCoup.setText("Gagne !       En "+nbCoup+" coups");
				}
			}
		}
	}

	/* Echange les positions des ImageView */
	public void changePos(int i)
	{
		/* Recupere les positions */
		float holeX = imgIsee[posEmpty].getX();
		float holeY = imgIsee[posEmpty].getY();

		float iX = imgIsee[i].getX();
		float iY = imgIsee[i].getY();

		/* Echange les places */
		imgIsee[posEmpty].setX(iX);
		imgIsee[posEmpty].setY(iY);

		imgIsee[i].setX(holeX);
		imgIsee[i].setY(holeY);
	}

	/* Creation du tableau random */
	public void createRandomUniqueList()
	{
		int index = 0;
		while (index < nbImageViewCreated) {
			int nouvelElement = r.nextInt(nbImageViewCreated)+1;
			if (!randomList.contains(nouvelElement)) {
				randomList.add(nouvelElement);
				index++;
			}
		}
	}

	/* Creation de toutes les Bitmap coupees */
	public void createBitmap(int nbL, int nbC)
	{
		imgIsee[0].buildDrawingCache();
		bip[0] = imgIsee[0].getDrawingCache();
		
		calculatedWidth = bip[0].getWidth() /nbC;
		calculatedHeight = bip[0].getHeight()/nbL;
		nbImageViewCreated = nbL * nbC;
		
		/* Prend les preferences de l'ImageView */
		try {
			if(prefs.getString("iut.picturama.holeColor", null).toString().equals("RGB_565"))
				bmpEmpty = Bitmap.createBitmap( calculatedWidth, calculatedHeight, Config.RGB_565);		//Noir
			else
				bmpEmpty = Bitmap.createBitmap( calculatedWidth, calculatedHeight, Config.ARGB_8888);	//Transparent
		} catch(Exception e) {
			bmpEmpty = Bitmap.createBitmap( calculatedWidth, calculatedHeight, Config.ARGB_8888);
		}

		int index = 0;
		int widthC = 0;
		int heightL = 0;
		createRandomUniqueList();
		//Log.e("randomList", ""+randomList.toString());
		for(int l=0; l<nbL; l++)
		{
			for(int c=0; c<nbC; c++)
			{
				index++;
				widthC = 0+calculatedWidth*c;
				heightL = 0+calculatedHeight*l;

				bip[index] = Bitmap.createBitmap(bip[0], widthC, heightL, calculatedWidth, calculatedHeight);
			}
		}

		createImageViewPosition(nbL, nbC);
	}

	/* Place les images en position random */
	public void createImageViewPosition(int nbL, int nbC)
	{
		int index = 0;
		int widthC = 0;
		int heightL = 0;
		int startPos = (int) imgIsee[0].getY()+bip[0].getHeight()+(DECALAGE*15);
		for(int l=0; l<nbL; l++)
		{
			for(int c=0; c<nbC; c++)
			{
				index++;
				widthC = 0+calculatedWidth*c;
				heightL = 0+calculatedHeight*l;

				createImageViewFromBitmap(bip[randomList.get(index-1)], randomList.get(index-1));
				setPositionToImageView(randomList.get(index-1), widthC+DECALAGE*c, heightL+DECALAGE*l+startPos-DECALAGE*(nbL+2));
			}
		}

		posEmpty = nbImageViewCreated;
		bip[posEmpty] = bmpEmpty;
		imgIsee[posEmpty].setImageBitmap(bip[posEmpty]);
	}

	/* Creation d'une ImageView a partir d'un Bitmap */
	public void createImageViewFromBitmap(Bitmap bip, int index)
	{
		//Create and add ImageView
		imgIsee[index] = new ImageView(this);
		imgIsee[index].setImageBitmap(bip);
		relLay.addView(imgIsee[index], params);
		imgIsee[index].getLayoutParams().width=bip.getWidth();
		imgIsee[index].getLayoutParams().height=(bip.getHeight());
		imgIsee[index].buildDrawingCache();

		//Set Listeners
		imgIsee[index].setOnClickListener(this);
		imgIsee[index].setTag("ImageView"+index);
		imgIsee[index].setId(index);
		System.out.println("imgID "+imgIsee[index].getId());
		//Log.e("Image Affichee",""+index+" Width:"+imgIsee[index].getLayoutParams().width+" Height:"+imgIsee[index].getLayoutParams().height);
	}

	/* Positionne une ImageView  --  Requiert Android 3.0*/
	public void setPositionToImageView(int index, int top, int left)
	{
		imgIsee[index].setX(top);
		imgIsee[index].setY(left);
	}

	/* Verification si l'image clique est voisine a l'image vide */
	public boolean verifyNearHole(int index)	//index image click		index 6 hole
	{
		//Haut
		if(imgIsee[posEmpty].getX()==imgIsee[index].getX() && imgIsee[posEmpty].getY()-(calculatedHeight+DECALAGE*10)<=imgIsee[index].getY() && (imgIsee[posEmpty].getY()-DECALAGE)>=imgIsee[index].getY())
			return true;
		
		//Gauche
		if(imgIsee[posEmpty].getY()==imgIsee[index].getY() && imgIsee[posEmpty].getX()-(calculatedWidth+DECALAGE*10)<=imgIsee[index].getX() && (imgIsee[posEmpty].getX()-DECALAGE)>=imgIsee[index].getX())
			return true;

		//Bas
		if(imgIsee[posEmpty].getX()==imgIsee[index].getX() && imgIsee[posEmpty].getY()+(calculatedHeight+DECALAGE*10)>=imgIsee[index].getY() && (imgIsee[posEmpty].getY()+DECALAGE)<=imgIsee[index].getY())
			return true;
		
		//Droite
		if(imgIsee[posEmpty].getY()==imgIsee[index].getY() && imgIsee[posEmpty].getX()+(calculatedWidth+DECALAGE*10)>=imgIsee[index].getX() && (imgIsee[posEmpty].getX()+DECALAGE)<=imgIsee[index].getX())
			return true;
		
		return false;
	}

	/* Verification de la victoire */
	public boolean verifWin()
	{
		int count=0;
		int index=0;

		float ancienX=0;
		float ancienY=0;

		for(int l=1; l<=nbL; l++)
		{
			for(int c=1; c<=nbC; c++)
			{
				index++;
				if (imgIsee[index].getX()>=ancienX-DECALAGE*6 && imgIsee[index].getY()>ancienY-DECALAGE*6)
				{
					ancienX=imgIsee[index].getX();
					ancienY=imgIsee[index].getY();
					count++;
				}
//				System.out.println("imgID "+imgIsee[index].getId()+"  count "+count+"  ancienX "+ancienX+"  ancienY "+ancienY+"  imgX"+imgIsee[index].getX()+"  imgY"+imgIsee[index].getY());
			}
			ancienX=0;
		}
//		System.out.println("count "+count+" = "+nbImageViewCreated+" nbImageViewCreated");
		if(count == nbImageViewCreated)
		{
			isWin = true;
			return true;
		}
		return false;
	}

	/* Rend (in)visible les boutons principaux */
	public void buttonsSetVisibility(int visibility)
	{
		butSplitDeuxXTrois.setVisibility(visibility);
		butSplitQuatreXSix.setVisibility(visibility);
		butSplitHuitXHuit.setVisibility(visibility);
		butAutreImage.setVisibility(visibility);
	}

	/* Gere le resultat des startActivityForResult(Intent, int) */
	protected void onActivityResult(int requestCode, int resultCode, Intent data)
	{
		/* Appareil photo */
		if (requestCode == CAMERA_REQUEST && resultCode == RESULT_OK)
		{  
			bip[0] = (Bitmap) data.getExtras().get("data"); 
			imgIsee[0].setImageBitmap(bip[0]);
		}
		
		/* Galerie */
		if (requestCode == SELECT_PHOTO && resultCode == RESULT_OK)
		{  
			String[] filePathColumn = {MediaStore.Images.Media.DATA};

			Cursor cursor = getContentResolver().query(data.getData(), filePathColumn, null, null, null);
			cursor.moveToFirst();

			String filePath = cursor.getString(cursor.getColumnIndex(filePathColumn[0]));
			cursor.close();

			bip[0] = BitmapFactory.decodeFile(filePath);
			imgIsee[0].setImageBitmap(bip[0]);
		} 
	}

	protected void onRestoreInstanceState(Bundle savedInstanceState) {
		super.onRestoreInstanceState(savedInstanceState);
		// Read values from the "savedInstanceState"-object and put them in your textview
	}

	protected void onSaveInstanceState(Bundle outState) {
		// Save the values you need from your textview into "outState"-object
		super.onSaveInstanceState(outState);
	}

	/* Telecharge une image depuis internet */
	public class DownloadImagesTask extends AsyncTask<ImageView, Void, Bitmap>
	{
		ImageView imageView = null;
		/* Telecharge en tache de fond */
		protected Bitmap doInBackground(ImageView... imageViews) {
			this.imageView = imageViews[0];
			return download_Image((String)imageView.getTag());
		}

		/* Met l'image telecharge dans l'ImageView */
		protected void onPostExecute(Bitmap result) {
			if(result!=null)
				imageView.setImageBitmap(result);
			else {
				imageView.setTag("Probleme de connection avec le server");
			}
		}
		
		/* Telecharge l'image */
		private Bitmap download_Image(String url) {
			Bitmap bm = null;
			try {
				URL urlOfImage = new URL(url);
				bm = BitmapFactory.decodeStream(urlOfImage.openConnection().getInputStream());
			} catch (Exception e) {
				bm = null;
			}
			return bm;
		}
	}

	/* Verifie si le telephone est connecte */
	public boolean isOnline()
	{
		ConnectivityManager connec = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
		if (connec != null && (connec.getNetworkInfo(1).getState() == NetworkInfo.State.CONNECTED) ||(connec.getNetworkInfo(0).getState() == NetworkInfo.State.CONNECTED)){ 
			return true;
		}else if (connec.getNetworkInfo(0).getState() == NetworkInfo.State.DISCONNECTED ||  connec.getNetworkInfo(1).getState() == NetworkInfo.State.DISCONNECTED ) {             
			return false;
		}
		return false;
	}
}